﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace Notoric.View.Music.CWNotation.Controls
{
    /// <summary>
    /// Visualizes a <see cref="ViewModel.Elements.CWNotation.DynamicsProgressMark"/>
    /// </summary>
    public partial class DynamicsProgressMark : UserControl
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicsProgressMark"/> class.
        /// </summary>
        public DynamicsProgressMark()
        {
            InitializeComponent();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the DataContextChanged event of the UserControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (mark != null)
                mark.PropertyChanged -= mark_PropertyChanged;

            mark = DataContext as ViewModel.Elements.CWNotation.DynamicsProgressMark;

            if (mark != null)
                mark.PropertyChanged += new PropertyChangedEventHandler(mark_PropertyChanged);

            SetVisualization();
        }

        /// <summary>
        /// Occurs when a property of the visualized mark has changed.
        /// </summary>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void mark_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Visualization")
                SetVisualization();
            else if (e.PropertyName == "IsSelected")
            {
                if (mark.IsSelected && mark.Visualization == ViewModel.Elements.CWNotation.DynamicsProgressDisplayMode.Hairpin)
                {
                    PART_EndsThumb.Visibility = System.Windows.Visibility.Visible;
                    PART_PointThumb.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    PART_EndsThumb.Visibility = System.Windows.Visibility.Collapsed;
                    PART_PointThumb.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the menu_ProgressType control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void menu_ProgressType_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.Elements.CWNotation.DynamicsProgressType progressType = ViewModel.Elements.CWNotation.DynamicsProgressType.Crescendo;

            if (sender == menu_Decrescendo)
                progressType = ViewModel.Elements.CWNotation.DynamicsProgressType.Decrescendo;
            else if (sender == menu_Diminuendo)
                progressType = ViewModel.Elements.CWNotation.DynamicsProgressType.Diminuendo;

            var cmd = mark.CreateSetProgressTypeCommand(progressType);
            cmd.Execute(null);
        }

        /// <summary>
        /// Handles the Checked event of the menu_Abbreviated control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void menu_Abbreviated_Checked(object sender, RoutedEventArgs e)
        {
            var cmd = mark.CreateSetAbbreviatedCommand(true);
            cmd.Execute(null);
        }

        /// <summary>
        /// Handles the Unchecked event of the menu_Abbreviated control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void menu_Abbreviated_Unchecked(object sender, RoutedEventArgs e)
        {
            var cmd = mark.CreateSetAbbreviatedCommand(false);
            cmd.Execute(null);
        }

        /// <summary>
        /// Handles the Click event of the menu_Expression control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void menu_Expression_Click(object sender, RoutedEventArgs e)
        {
            var cmd = mark.CreateSetExpressionCommand(((MenuItem)sender).Tag.ToString());
            cmd.Execute(null);
        }

        /// <summary>
        /// Handles the Click event of the menu_VisualizationText control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void menu_VisualizationText_Click(object sender, RoutedEventArgs e)
        {
            var cmd = mark.CreateSetVisualizationCommand(ViewModel.Elements.CWNotation.DynamicsProgressDisplayMode.Text);
            cmd.Execute(null);
        }

        /// <summary>
        /// Handles the Click event of the menu_VisualizationHairpin control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void menu_VisualizationHairpin_Click(object sender, RoutedEventArgs e)
        {
            var cmd = mark.CreateSetVisualizationCommand(ViewModel.Elements.CWNotation.DynamicsProgressDisplayMode.Hairpin);
            cmd.Execute(null);
        }

        /// <summary>
        /// Handles the DragDelta event of the PART_PointThumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
        private void PART_PointThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            mark.HairpinPoint = new Point(mark.HairpinPoint.X + e.HorizontalChange, mark.HairpinPoint.Y);
        }

        /// <summary>
        /// Handles the DragCompleted event of the PART_PointThumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragCompletedEventArgs"/> instance containing the event data.</param>
        private void PART_PointThumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {
            mark.CommitChanges();
        }

        /// <summary>
        /// Handles the DragDelta event of the PART_EndsThumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
        private void PART_EndsThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            mark.HairpinEnd1 = new Point(mark.HairpinEnd1.X + e.HorizontalChange, mark.HairpinEnd1.Y);
            mark.HairpinEnd2 = new Point(mark.HairpinEnd2.X + e.HorizontalChange, mark.HairpinEnd2.Y);
        }

        /// <summary>
        /// Handles the DragCompleted event of the PART_EndsThumb control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragCompletedEventArgs"/> instance containing the event data.</param>
        private void PART_EndsThumb_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {
            mark.CommitChanges();
        }

        /// <summary>
        /// Handles the MouseLeftButtonDown event of the UserControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void UserControl_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (mark.IsSelected)
                mark.FindOwner<ViewModel.Elements.CWNotation.MusicSectionInterior>().SelectedProgressMark = null;
            else
                mark.FindOwner<ViewModel.Elements.CWNotation.MusicSectionInterior>().SelectedProgressMark = mark;

            e.Handled = true;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Sets the visualization.
        /// </summary>
        private void SetVisualization()
        {
            if (mark == null)
            {
                PART_TextThumb.Visibility = Visibility.Collapsed;
                PART_Hairpin.Visibility = Visibility.Collapsed;
                return;
            }

            if (mark.Visualization == ViewModel.Elements.CWNotation.DynamicsProgressDisplayMode.Hairpin)
            {
                PART_Hairpin.Visibility = Visibility.Visible;
                PART_TextThumb.Visibility = Visibility.Collapsed;
                menu_VisualizationHairpin.IsChecked = true;
                menu_VisualizationText.IsChecked = false;
                if (mark.IsSelected)
                {
                    PART_EndsThumb.Visibility = System.Windows.Visibility.Visible;
                    PART_PointThumb.Visibility = System.Windows.Visibility.Visible;
                }
            }
            else
            {
                PART_Hairpin.Visibility = Visibility.Collapsed;
                PART_TextThumb.Visibility = Visibility.Visible;
                menu_VisualizationHairpin.IsChecked = false;
                menu_VisualizationText.IsChecked = true;
                PART_EndsThumb.Visibility = System.Windows.Visibility.Collapsed;
                PART_PointThumb.Visibility = System.Windows.Visibility.Collapsed;
            }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds a reference to the visualized mark.
        /// </summary>
        private ViewModel.Elements.CWNotation.DynamicsProgressMark mark;

        #endregion
    }
}
